
#define MAX_PACKET (1400)
#define MAXWINDOW (50)
#define MAX_SEGMENT (MAX_PACKET - sizeof(struct lab6_header))

#define NORMAL ( 1 )
#define CLOSING ( 2 )
#define FIN_SENT ( 3 )



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/select.h>
#include <pthread.h>
#include <semaphore.h>

#define TIME_TO_WAIT (15000)

typedef pthread_mutex_t mutex;
typedef sem_t semaphore;

int nextSlot;
int startSlot;
int currentTimeout;
int currentRTT;
int currentVar;
int windowSize;


int recipientClosed;
int recvBase;
int receivedFin;
int sequenceNum;

int state;
int closed;

struct lab6_header {
  uint16_t packet_num;
  uint32_t sequence_num;
  uint32_t ack_flag;
  uint16_t fin_flag;
  uint16_t length;

};

typedef struct {
  
  char data[MAX_PACKET];
  int sequenceNumber;
  int length;
  int ack;
  int sendTime;
  int recvTime;
  int timeout;

} packet;



void * senderFunc( void * );
void sendPacket( int sock, packet * data );
int receiveAcks( int sock, int num );
void updateVariables( int localStartSlot, int sendNum );
void updateTimeRTT( int, int );
int my_recv( int sock, void * buffer, size_t length );
void send_ack( int sock, struct lab6_header * header );
int my_socket( int domain, int type, int protocol );
void my_send(int sock, void *buf, size_t len);
int my_close(int sock);

int timeval_to_msec(struct timeval *t) ;
void msec_to_timeval(int millis, struct timeval *out_timeval) ;
int current_msec() ;
int my_connect(int socket,struct sockaddr_in *toaddr,int addrsize) ;
int my_rtt(int sock) ;
int my_max_window(int sock) ;

void * Malloc( size_t );

